package com.lark.utils;

import javafx.concurrent.Task;
import lombok.extern.slf4j.Slf4j;

import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 异步任务
 *
 * @param <T>
 */
@Slf4j
public class TaskUtil<T> extends Task<T> {

    private final String message;

    private final Supplier<T> function;

    private Consumer<T> success;

    private Consumer<T> failure;

    public TaskUtil(String message, Supplier<T> function) {
        this(message, function, null, null);
    }

    public TaskUtil(String message, Supplier<T> function, Consumer<T> success, Consumer<T> failure) {
        this.message = message;
        this.function = function;
        this.success = success;
        this.failure = failure;
    }

    @Override
    protected T call() throws Exception {
        return function.get();
    }

    @Override
    protected void succeeded() {
        super.succeeded();
        Optional.ofNullable(success).ifPresent(consumer -> consumer.accept(getValue()));
        log.info("Task {} succeeded", message);
    }

    @Override
    protected void failed() {
        super.failed();
        Optional.ofNullable(failure).ifPresent(consumer -> consumer.accept(getValue()));
        log.error("Task {} failed", message, getException());
    }

    public static <T> Task<T> runOnce(String message, Supplier<T> function) {
        return runOnce(message, function, null, null);
    }

    public static <T> Task<T> runOnce(String message, Supplier<T> function, Consumer<T> success, Consumer<T> failure) {
        Task<T> task = new TaskUtil<>(message, function, success, failure);
        Thread.startVirtualThread(task);
        return task;
    }
}
